import React, { useCallback } from 'react';
import { useAsyncState, asCallPromise, asTrackPromise, usePromise } from 'hooklib/async';
import s from './common.less';
import { ShowAs } from './common';

function rand() {
  return Math.floor(Math.random() * 100);
}

// 模拟一个返回 promise 的异步函数
function asWait(timeout: number) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (Math.random() < 0.3) {
        return reject(new Error(`error no.${rand()}`))
      }
      resolve(rand());
    }, timeout);
  });
}

export default function CallPromiseExample() {
  // 定义多个异步操作状态跟踪变量
  const as1 = useAsyncState('as1');
  const as2 = useAsyncState('as2');
  const as3 = useAsyncState('as3');

  // asCallPromise/asTrackPromise 可以用于跟踪 promise 变化到 IAsyncState 状态
  const onCallPromise = useCallback(() => {
    // 1. lazy 的异步函数，由 asCallPromise 控制开始执行
    asCallPromise(as1, () => asWait(300));

    // 2. 直接执行异步函数，由 asTrackPromise 跟踪返回的 promise 的状态变化
    asTrackPromise(as2, asWait(100));

    // 3. 同上，但是触发执行在前面，执行的结果 promise 带入 asTrackPromise
    const promise3 = asWait(200);
    asTrackPromise(as3, promise3);
  }, []);

  // 当 as2 重新执行状态变化，且执行成功，并且结果符合返回就触发本 fn 执行，并跟踪到 as4 下
  // 注意，deps 第一个值，如果是假值，不触发 fn 执行，忽略掉
  const as4 = usePromise('as4', [as2.o && as2.d > 50], () => {
    return asWait(3000);
  });

  return (
    <div>
      <button onClick={onCallPromise}>onCallPromise</button>
      <div className={s.grid}>
        <ShowAs as={as1} />
        <ShowAs as={as2} />
        <ShowAs as={as3} />
        <ShowAs as={as4} />
      </div>
    </div>
  )
}
